/*=====================================================================*
 *                   Copyright (C) 2011 Paul Mineiro                   *
 * All rights reserved.                                                *
 *                                                                     *
 * Redistribution and use in source and binary forms, with             *
 * or without modification, are permitted provided that the            *
 * following conditions are met:                                       *
 *                                                                     *
 *     * Redistributions of source code must retain the                *
 *     above copyright notice, this list of conditions and             *
 *     the following disclaimer.                                       *
 *                                                                     *
 *     * Redistributions in binary form must reproduce the             *
 *     above copyright notice, this list of conditions and             *
 *     the following disclaimer in the documentation and/or            *
 *     other materials provided with the distribution.                 *
 *                                                                     *
 *     * Neither the name of Paul Mineiro nor the names                *
 *     of other contributors may be used to endorse or promote         *
 *     products derived from this software without specific            *
 *     prior written permission.                                       *
 *                                                                     *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND              *
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,         *
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES               *
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE             *
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER               *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,                 *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES            *
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE           *
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR                *
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF          *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY              *
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE             *
 * POSSIBILITY OF SUCH DAMAGE.                                         *
 *                                                                     *
 * Contact: Paul Mineiro <paul@mineiro.com>                            *
 *=====================================================================*/

#ifndef __EXAMPLE_HH__
#define __EXAMPLE_HH__

#include <boost/interprocess/detail/atomic.hpp>
#include <boost/shared_ptr.hpp>
#include <string>
#include <vector>

#include "feature.hh"
#include "sparsevector.hh"

namespace flassol
{
  struct GeneralExample
    {
      char*                                     label;
      char*                                     importance;
      char*                                     tag;
      boost::shared_ptr<IndexedFeatureSet>      f;
      boost::shared_ptr<std::string>            buf;
    };

  struct EstimateResult
    {
      float       p;
      float       wdotx;
      float       adotb;
      float       xnorm;
      float       anormplusbnorm;
      uint64_t    n;
      bool        skip;

      EstimateResult () : p (0), 
                          wdotx (0),
                          adotb (0),
                          xnorm (0), 
                          anormplusbnorm (0),
                          n (0),
                          skip (false)
        { 
        }

      EstimateResult&
      reset ()
        {
          p = 0;
          wdotx = 0;
          adotb = 0;
          xnorm = 0;
          anormplusbnorm = 0;
          n = 0;

          return *this;
        }

      EstimateResult&
      operator+= (const EstimateResult& r)
        {
          p += r.p;
          wdotx += r.wdotx;
          adotb += r.adotb;
          xnorm += r.xnorm;
          anormplusbnorm += r.anormplusbnorm;
          n += r.n;

          return *this;
        }
    };

  typedef std::vector<EstimateResult> EstimateResultVector;
  typedef std::vector<EstimateResultVector> EstimateResultMatrix;
  typedef std::vector<float> FloatVector;
  typedef std::vector<FloatVector> FloatMatrix;

  struct RegressionExample
    {
      volatile boost::uint32_t*                 usecount;
      volatile boost::uint32_t*                 estimationcount;
      volatile boost::uint32_t*                 adaptivecount;

      boost::optional<float>                    label;
      float                                     importance;
      char*                                     tag;
      boost::shared_ptr<IndexedFeatureSet>      f;

      boost::shared_ptr<EstimateResultMatrix>   partials;
      boost::shared_ptr<FloatMatrix>            norm_partials;

      boost::shared_ptr<std::string>            buf;

      RegressionExample () : usecount (0),
                             estimationcount (0),
                             adaptivecount (0),
                             label (),
                             importance (),
                             tag (0),
                             f (),
                             partials (),
                             norm_partials (),
                             buf ()
        {
        }
    };

  struct UpdateInfo
    {
      float gsq;
      float adaptivexnorm; /* x . G^{(t)} . x */
      float sh;
      float decay;
      bool  adaptive;

      UpdateInfo () : gsq (0),
                      adaptivexnorm (0),
                      sh (0),
                      decay (1.0f),
                      adaptive (false)
        { 
        }
    };

  typedef std::vector<UpdateInfo> UpdateInfoVector;
  typedef std::vector<UpdateInfoVector> UpdateInfoMatrix;

  struct CSMCExample
    {
      volatile boost::uint32_t*                 usecount;
      volatile boost::uint32_t*                 estimationcount;
      volatile boost::uint32_t*                 adaptivecount;
      volatile boost::uint32_t*                 updatecount;

      boost::optional<SparseVector>             cost;
      char*                                     tag;
      boost::shared_ptr<IndexedFeatureSet>      f;

      boost::shared_ptr<EstimateResultMatrix>   initials;
      boost::shared_ptr<EstimateResultMatrix>   partials;
      boost::shared_ptr<FloatMatrix>            norm_partials;

      boost::shared_ptr<std::string>            buf;

      CSMCExample () : usecount (0),
                       estimationcount (0),
                       adaptivecount (0),
                       updatecount (0),
                       cost (),
                       tag (0),
                       f (),
                       partials (),
                       norm_partials (),
                       buf ()
        {
        }
    };
}

#endif // __EXAMPLE_HH__
